#include "LCD1602.H"
#include <intrins.h>
#define DATA 0
#define OPERATOR 1
#define CALC 2
UINT8 code AUTO_ISP[2] = { 0x55, 0xaa };
UINT8 code Seg_Table[21] = { 0xC0,/*0*/ 0xF9,/*1*/ 0xA4,/*2*/ 0xB0,/*3*/
									  0x99,/*4*/ 0x92,/*5*/ 0x82,/*6*/ 0xF8,/*7*/
									  0x80,/*8*/ 0x90,/*9*/ 0x40,/*0*/ 0x79,/*1*/
									  0x24,/*2*/ 0x30,/*3*/ 0x19,/*4*/ 0x12,/*5*/
									  0x02,/*6*/ 0x78,/*7*/ 0x00,/*8*/ 0x10,/*9*/
									  0xff //all off
									  };
UINT8 code Pos_Dis_Buf[5] = { 0xef, 0xdf, 0xbf, 0x7f, 0xff };
UINT8 Digit[4] = { 0 };
UINT8 Position = 0;
UINT16 X, Y, SUM, ADDNUM, SHU;
UINT8 KeyCode;
UINT8 LastKeyCode = 0xff;
UINT8 State = DATA;
UINT16 Para1, Para2, Result;
UINT8 KeyCounter = 0;
bit Down_flag, ADDFLAG, MULFLAG, SUBFLAG; // 检测到第一个合法的下载保留字
bit DotFlag = 0;
sbit SEG_BEEP = P3 ^ 5;
sbit SEG_DIN = P3 ^ 6;
sbit SEG_CLK = P3 ^ 7;
UINT16 Dis_Buf[4] = { 20, 20, 20, 10 };
UINT16 Key_Buf[4] = { 0 };

void Delay(UINT16 n) {
	while (--n);
}

void Init_UART(void) {
	SCON = 0x50; // 串口工作在方式一(起始位 +8bit 数据 + 停止位)，允许发送和接收
	AUXR = 0x15; // 使用独立的波特率发生器， 1T 模式，独立的波特率发生器使能
	BRT = 0xfa; // BRT = 256 - INT(fosc/baud/32 + 0.5) Fosc = 11.0592M,Baud = 57600bps
	PS = 1; // 串口中断优先级高
	ES = 1; // 串口中断使能
	EA = 1; // 总中断使能
}

void UART_Send_Char(UINT8 ucData) {
	SBUF = ucData;
	while (!TI)
		;
	TI = 0;
}

void UART_Send_Str(UINT8* Str) {
	while (*Str) {
		UART_Send_Char(*Str);
		Str++;
	}
}

void Bit_Display(UINT8 Pos, UINT8 ucDATA, bit Point) {
	UINT8 i;
	UINT8 ucTemp;
	ucTemp = Seg_Table[ucDATA]; // 查段码表
	if (Point) {
		ucTemp &= 0x7f;
	}
	P4 = Pos_Dis_Buf[1]; // 关闭所有显示
	for (i = 0; i < 8; i++) {
		SEG_DIN = ucTemp & 0x80; // 每次取最高位，最高位为 1 ，则 SEG_DIN=1 ；反之亦然
		SEG_CLK = 0;
		SEG_CLK = 1; //产生 74164 移位时钟上升沿
		ucTemp <<= 1;
	}
	P4 = Pos_Dis_Buf[Pos]; // 使能位选
	Delay(100);
}

void Seg_Display(UINT16 uiData) {
	UINT8 i;
	Digit[0] = uiData / 1000; // 千位
	Digit[1] = uiData / 100 % 10; // 百位
	Digit[2] = uiData / 10 % 10; // 十位
	Digit[3] = uiData % 10; // 个位
	while (1) {
		for (i = 0; i < 4; i++) {
			Bit_Display(i, Digit[i], 1);
		}
	}
}

void Init_Timer0(void) {
	TMOD = 0x11;
	TH0 = 0xdc;
	TL0 = 0x00;
	ET0 = 1;
	EA = 1;
	TR0 = 1;
}

void LED(void) {
	P2 = (P2 << 7) | (P2 >> 1);
}

void Init_GPIO(void) {
	P4SW = 0x70; // 设定 P4 口为 I/O 口	
}

void Init_System(void) {
	BEEP_ON();
	Delay(0xffff);
	BEEP_OFF();
	Delay(0xffff);
	BEEP_ON();
	Delay(0xffff);
	BEEP_OFF();
	Init_GPIO();
	Init_UART();
	Init_LCD1602();
	Init_Timer0();
}

void KeyScan() {
	P2 = 0x0f;
	if (P2 != 0x0f) {
		Delay(500);
		if (P2 != 0x0f) {
			X = P2;
			P2 = 0xf0;
			if (P2 != 0xf0) {
				Y = P2;
			}
			KeyCode = X | Y;
			Delay(8000);
		}
	} else {
		KeyCode = 0xff;
		return;
	}
}

void Display(UINT16 Num) {
	UINT16 NumTemp = Num;
	UINT8 i = 0;
	while (NumTemp) {
		NumTemp /= 10;
		i++;
	}
	if (i == 1) {
		Dis_Buf[0] = 20; // 千位
		Dis_Buf[1] = 20; // 百位
		Dis_Buf[2] = 20; // 十位
		Dis_Buf[3] = Num % 10 + 10; // 个位 	
	} else if (i == 2) {
		Dis_Buf[0] = 20; // 千位
		Dis_Buf[1] = 20; // 百位
		Dis_Buf[2] = Num / 10 % 10; // 十位
		Dis_Buf[3] = Num % 10 + 10; // 个位 		
	} else if (i == 3) {
		Dis_Buf[0] = 20; // 千位
		Dis_Buf[1] = Num / 100 % 10;
		; // 百位
		Dis_Buf[2] = Num / 10 % 10; // 十位
		Dis_Buf[3] = Num % 10 + 10; // 个位 	
	} else if (i == 4) {
		Dis_Buf[0] = Num / 1000; // 千位
		Dis_Buf[1] = Num / 100 % 10; // 百位
		Dis_Buf[2] = Num / 10 % 10;
		Dis_Buf[3] = Num % 10 + 10; // 个位
	}
}

void main() {
	UINT16 ttemp;
	Init_System();
	while (1) {
		while (1) {
			KeyScan();
			switch (KeyCode) {
			case 119: // 1
				ttemp = 1110;
				break;

			case 123: // 2
				ttemp = 2220;
				break;

			case 125: // 3
				ttemp = 3330;
				break;

			case 183: // 4
				ttemp = 4440;
				break;

			case 187: // 5
				ttemp = 5550;
				break;

			case 189: // 6
				ttemp = 6660;
				break;

			case 215: // 7
				ttemp = 7770;
				break;

			case 219: // 8
				ttemp = 8880;
				break;

			case 221: // 9
				ttemp = 9990;
				break;

			case 231: // +
				ttemp++;
				break;

			case 237:
				ttemp--;
				if (ttemp <= 10)
					ttemp = 10;
				break;
			}
			Display(ttemp);
		}
	}
}

void UART0_ISR()
interrupt 4
{
	if(RI)
	{
		RI = 0;
		{
			if(SBUF == AUTO_ISP[0])
			{
				Down_flag = 1;
			}
			else
			if(SBUF == AUTO_ISP[1])
			{
				if(Down_flag == 1)
				{
					Down_flag = 0;
					BEEP_ON();
					Delay(0xffff);
					BEEP_OFF();
					IAP_CONTR = 0x60;
				}
			}
		}
	}
}

void timer0_ISR()
interrupt 1
{
	UINT8 ucTemp;
	TH0 = 0xee;
	TL0 = 0xff;

	P4 = Pos_Dis_Buf[Position];
	ucTemp = Seg_Table[Dis_Buf[Position]]; // 查段码表
	for(i = 0; i < 8; i++)
	{
		SEG_DIN = ucTemp & 0x80; // 每次取最高位，最高位为 1 ，则 SEG_DIN=1 ；反之亦然
		SEG_CLK = 0;
		SEG_CLK = 1;// 产生 74164 移位时钟上升沿
		ucTemp <<= 1;
	}
	Position++;
	if(Position==4)
	{
		Position = 0;
	}
}